home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Tools & Apps / OS⁄Toolbox / DefProcs / butcdef.a next >
Encoding:
Text File  |  1990-09-14  |  29.6 KB  |  868 lines  |  [TEXT/MPS ]

  1. ;EASE$$$ READ ONLY COPY of file “butcdef.a”
  2. ; 1.0    CCH 11/16/1988 Added to EASE.
  3. ; END EASE MODIFICATION HISTORY 
  4. ;
  5. ;File ButCDef.ASM
  6. ;--------------------------------------------------------------------------
  7. ;
  8. ;  Standard Button Definition Procedure for the
  9. ;    MacIntosh Control Manager
  10. ;
  11. ;  written by Andy Hertzfeld  August, 1982
  12. ;
  13. ;  (c) 1982 by Apple Computer, Inc.  All rights reserved.
  14. ;
  15. ;     This file contains the control definition procedures
  16. ;     that define the standard "button" type controls.  These
  17. ;     include PushButtons, CheckBoxes, and a checkBox variant called
  18. ;     RadioButton
  19. ;
  20. ;  Modification History:
  21. ;
  22. ;     22-Aug-82    AJH  Added clipping, centering to PushButProc
  23. ;     25-Aug-82    AJH  Fixed corner-clobber bug in pushButProc
  24. ;     29-Aug-82    AJH  Added "255" hiliting,
  25. ;     29-Sep-82    AJH  Added CheckBox control definition procedure
  26. ;     03-Oct-82    AJH  Fixed bug in scrollBar positioning -- wasn't ctl relative
  27. ;     05-Oct-82    AJH  Fixed checkBox flashing, added code saving optimizations
  28. ;     10-Oct-82    AJH  Converted for QuickDraw Trap Interface
  29. ;     17-Oct-82    AJH  Made controlProcs preserve A1
  30. ;     14-Nov-82    AJH  Improved PushButton roundness scaling; removed box in arrowBits
  31. ;     16-Nov-82    AJH  Made branch tables offset based
  32. ;     28-Dec-82    AJH  Put button definitions in their own file
  33. ;     11-Mar-83    AJH  fixed up check box drawing
  34. ;     27-Mar-83    AJH  made it respect initial clip in button drawing
  35. ;     01-Apr-83    AJH  made it use hardwired gray
  36. ;     04-Apr-83    AJH  made it force size 12 for text
  37. ;     07-Jun-83    AJH  fixed scrambling bug, changed check draw for new QuickDraw
  38. ;     29-Aug-83    AJH  fixed scrambling bug in CalcPBut
  39. ;     27-Sep-83    AJH  made variants > 7 not force the system font
  40. ;     12-Oct-83    AJH  changed button disabling
  41. ;     17-Oct-83    AJH  back to "gray-out" button disabling
  42. ;     31-Dec-83    AJH  made text of checkBox/radioButtons grayed    out if disabled
  43. ;     14-Jan-85    JTC  convert to MDS
  44. ;     14-Feb-85    JTC  added res name
  45. ;     12-Mar-85    JTC  changed occurrences of LGlobals to GrafGlobals
  46. ;v2  16-May-85    EHB  only return "254" if point in control!
  47. ;v3  20-May-85    EHB  implemented Multi-Line buttons
  48. ;v4  26-Aug-85    EHB  made variable sized fonts work (ROM85>0 only)
  49. ;
  50. ;--Post Lonely Heiffer Release----------------------------------------------
  51. ;
  52. ;     <C59/30Jun86>    DAF     added color support for nuMac (mucho chango)
  53. ;    <C203/08Oct86>  DAF     updated color support on nuMac for RGBColors
  54. ;                            changed textMode to srcOr.
  55. ;    <C407/16Nov86>    DAF     changed textMode (again) to srcCopy, as per Cary's recommendation
  56. ;   <C424/18Nov86>     DAF     converted a BSET/BCLR to an HLock/HUnlock, in CalcPBut
  57. ;    <C560/21Dec86>  DAF     Added Mark Davis' code to allow reversed checkmarks for intl
  58. ;    <C637/14Jan87>    DAF     Changed textMode back to srcOR from srcCopy (sigh...)
  59. ;    <C700/26Jan87>  DAF     Universal version of butCDEF.a (version 10)
  60. ;     <C818/14Feb87>  DAF     Converted nuMac PaintRoundRgn to be unified with other Macs' Erase
  61. ;                         stopped setting backColor when drawing text.
  62. ;    <SMAB156/30Mar87>    DAF     Tested ROM version before using teSysJust.
  63. ;
  64.  
  65.  
  66.  
  67.             BLANKS        ON
  68.             STRING        ASIS
  69.  
  70.             PRINT        OFF
  71.             LOAD        'inc.sum.d'
  72.             LOAD        'nEqu.d'
  73.             INCLUDE        'colorEqu.a'
  74.             PRINT        ON
  75.             
  76. ;
  77. CDEF0        PROC        EXPORT
  78. ;
  79. ; FUNCTION PushButProc( selector:    INTEGER;        18
  80. ;            theControl: ControlHandle;                14
  81. ;            message:    INTEGER;                    12
  82. ;            param:        LongInt): LongInt;             8 : 20
  83. ;
  84. ;    PushButProc is the control definition procedure for simple pushButtons, one of the
  85. ; standard control types supported by the user interface toolBox.
  86. ;
  87.  
  88.  
  89. ;  And a stack frame definition
  90.  
  91. CtlHndl            EQU      14                ;incoming control handle param    <C59/30Jun86> DAF
  92. SavePen         EQU  -20
  93. Align            EQU     -21                ;a dead byte for IsColor        <C700/26Jan87> DAF
  94. IsColor            EQU     -22                ;do we have colorQD and toolbox [boolean]    <C700/26Jan87> DAF
  95. IndicatorRect    EQU  -30
  96. AuxCtlHndl        EQU     -34                ;handle of auxCtl ColorTable    <C59/30Jun86> DAF
  97. AuxCtlPtr        EQU     -38                ;ptr to auxCtl ColorTable        <C59/30Jun86> DAF
  98. ContentRGB        EQU     -44                ;window content color            <C59/30Jun86> DAF
  99. SavFgCol        EQU     -50                ;window port's RGBFgColor        <Cxxx/06Oct86> DAF
  100. SavBkCol        EQU     -56                ;window port's RGBBkColor        <Cxxx/06Oct86> DAF
  101. FrameSize        EQU     -56                ;                                <C59/30Jun86> DAF
  102.                 
  103. ;
  104.             BRA.S    @0                    ; skip header
  105.  
  106. ; standard header
  107.  
  108.             DC.W    0                    ; flags
  109.             DC.B    'CDEF'
  110.             DC.W    0
  111.             DC.W    10                    ; version #
  112. @0
  113.             LINK    A6,#FrameSize         ; set up a stack frame to address parameters <C59/30Jun86> DAF
  114.             
  115.             MOVEM.L D3-D7/A1-A4,-(SP)    ; save work registers
  116. ;
  117. ; buttons only handle messages 0,1 and 2
  118. ;
  119.             CMP     #3,12(A6)            ; inspect message value
  120.             BGE        DoneP1                ; if >2, nothing to do
  121. ;
  122. ; save the penState and set it our way
  123. ;
  124.             PEA     SavePen(A6)         ; push pointer to savePenState
  125.             _GetPenState                ; remember current penState
  126.             _PenNormal                    ; set the pen the way we want it
  127.  
  128.             
  129. ; Determine type of system.  We need to know if we have color QuickDraw and a color
  130. ;    window manager port.
  131.     
  132.             CMP.W    #$3FFF,ROM85        ; do we have color QD? 
  133.             SLS        IsColor(A6)            ; set boolean depending on color or B&W system
  134.             BHI.S    @BWSys                ; no, this system has B&W QD
  135.             
  136. ; save the current port's colors and textMode                        <C59/30Jun86> DAF
  137.             
  138.             MOVE.L    GrafGlobals(A5),A0    ; get pointer to grafGlobals    <C407/16Nov86> DAF
  139.             MOVE.L    thePort(A0),A0        ; get pointer to thePort        <C407/16Nov86> DAF
  140.             MOVE.W    txMode(A0),-(SP)    ; save the current text mode    <C407/16Nov86> DAF
  141.             
  142.             MOVE.W    #srcOR,-(SP)        ; push text mode                <C637/16Nov86> DAF
  143.             _TextMode                    ;                                <C407/16Nov86> DAF
  144.             
  145.             PEA        SavFgCol(A6)        ; save foreColor
  146.             _GetForeColor                ;
  147.             PEA        SavBkCol(A6)        ; save backColor too
  148.             _GetBackColor                ;
  149.  
  150. ;
  151. ; get the CtlAuxRec for this guy and lock its colortable            <C59/30Jun86> DAF
  152. ;
  153.             CLR.L    -(SP)                ; return the handle here
  154.             CLR.B    -(SP)                ; space for boolean func return
  155.             MOVE.L    CtlHndl(A6),-(SP)    ; push the control handle
  156.             PEA        6(SP)                ; push a pointer to placeholder
  157.             _GetAuxCtl                    ; get its auxRec
  158.             ADDQ    #2,SP                ; don't need boolean result
  159.             MOVE.L    (SP)+,A0            ; get auxCtl handle
  160.             MOVE.L    (A0),A0                ; a pointer to the auxCtlRec
  161.             MOVE.L    ctlCTable(A0),A0    ; get colortable's handle
  162.             MOVE.L    A0,AuxCtlHndl(A6)    ; save the handle
  163.             _HLock                        ; lock the handle
  164.             MOVE.L    (A0),AuxCtlPtr(A6)    ; save a pointer
  165.             
  166. ;
  167. ; get the WinAuxRec that this control is in and copy its content color to
  168. ;    the stack frame. 
  169. ;
  170.             
  171.             CLR.L    -(SP)                ; make a placeholder for a handle
  172.             CLR.B    -(SP)                ; room for a boolean result
  173.             MOVE.L    CtlHndl(A6),A0        ; get the controlHandle again
  174.             MOVE.L    (A0),A0                ; get a pointer
  175.             MOVE.L    contrlOwner(A0),-(SP) ; push the owning window pointer
  176.             PEA        6(SP)                ; pointer to the placeholder
  177.             _GetAuxWin                    ; get the window auxRec
  178.             ADDQ    #2,SP                ; bag the boolean
  179.             MOVE.L    (SP)+,A0            ; get the WinAuxRec handle
  180.             MOVE.L    (A0),A0                ; handle->ptr
  181.             MOVE.L    winCTable(A0),A0    ; get the colortable handle
  182.             MOVE.L    (A0),A0                ; handle->ptr
  183.             
  184.             MOVE.W    CTSize(A0),D0        ; get the table count
  185.             MULU.W    #8,D0                ; get a table index
  186. @1            
  187.             TST.W    CTTable+value(A0,D0)    ; is it wContentColor (=0)?
  188.             BEQ.S    @2                ; 
  189.             SUBQ    #8,D0                ; move to previous colorSpec
  190.             BGE.S    @1                    ; and loop back
  191.             CLR.L    D0                    ; if not found, just use the first one
  192. @2
  193.             MOVE.L    CTTable+rgb(A0,D0),ContentRGB(A6)    ; copy the color over
  194.             MOVE.W    CTTable+rgb+4(A0,D0),ContentRGB+4(A6) ; 
  195.             
  196. @BWSys
  197.  
  198. ;
  199. ; fetch the parameters into registers
  200. ;
  201.             LEA     8(A6),A0            ; get ptr to first parameter
  202.             MOVE.L    (A0)+,D3            ; get param in D3
  203.             MOVE.W    (A0)+,D0            ; get message
  204.             MOVE.L    (A0)+,A3            ; get the control handle
  205.             MOVE.W    (A0)+,D6            ; get selection index
  206.             MOVE.W    D6,D7                ; remember raw selection code
  207.             AND     #7,D6                ; strip high part of selection code
  208.  
  209.             CLR.L    (A0)                ; clear out function result
  210.             MOVE.L    (A3),A0             ; get control pointer in A0
  211. ;
  212. ; case out on the message number
  213. ;
  214.             ADD     D0,D0                ; double for word index
  215.             LEA     GoPushBut,A1        ; get table address
  216.             ADD     0(A1,D0),A1         ; compute dispatch address
  217.             JSR     (A1)                ; dispatch to appropriate routine
  218.  
  219. ;
  220. ; clean up color stuff                                                
  221.  
  222.             TST.B    IsColor(A6)            ; are we on a color system?            
  223.             BEQ.S    @NoColor1            ; if on B&W, then skip            
  224.  
  225.             MOVE.L    AuxCtlHndl(A6),A0    ; unlock the CDEF
  226.             _HUnlock
  227.             PEA        SavFgCol(A6)        ; restore the port colors
  228.             _RGBForeColor                ;
  229.             PEA        SavBkCol(A6)        ;
  230.             _RGBBackColor                ;
  231.             
  232.             _TextMode                    ; restore the textMode            <C407/16Nov86> DAF
  233.             
  234. @noColor1                                ; END OF A COLOR-ONLY SECTION
  235.  
  236. ;
  237. ; restore original pen state
  238. ;
  239.             PEA     SavePen(A6)         ; push savePenState
  240.             _SetPenState                ; restore original pen state
  241. ;
  242. ; we're done -- restore registers and return to caller
  243. ;
  244. DoneP1
  245.             MOVEM.L (SP)+,D3-D7/A1-A4    ; restore work registers
  246.             UNLK    A6                    ; unlink stack frame
  247. TenBytExit    MOVE.L    (SP)+,A0            ; get return address
  248.             ADD     #12,SP                ; strip parameters
  249.             JMP     (A0)                ; return to caller
  250. ;
  251. ; PushButProc dispatch table -- entries must be long branches!
  252. ;
  253. GoPushBut
  254.             DC.W    DrawPBut-GoPushBut    ; draw is message 0
  255.             DC.W    HitPBut-GoPushBut    ; hit test is message 1
  256.             DC.W    CalcPBut-GoPushBut    ; calc regions is message 2
  257.  
  258. ButStub     RTS
  259.  
  260.  
  261. ; SetUpColor takes a window part identifier in D0, finds the corresponding
  262. ;    part in the AuxWinTable (the part code is in the .value field) and returns
  263. ;    a pointer to its RGB on the stack.  If the requested part is not found,
  264. ;    the first color table element is used (I'd use frameColor, but that might
  265. ;    not be there!).  Trashes A0/D0.
  266.  
  267. SetUpColor
  268.             MOVE.L    D1,-(SP)            ; save a register
  269.             MOVE.L    AuxCtlPtr(A6),A0    ; get the color table pointer
  270.             MOVE.W    CTSize(A0),D1        ; get the color table size
  271.             MULU    #8,D1                ; convert to color table index
  272. LegalIndex    
  273.             CMP.W    CTTable+value(A0,D1),D0    ; is this the one?
  274.             BEQ.S    FoundIt                ; if equal, then done
  275.             SUB.W    #8,D1                ; try the previous one
  276.             BGE.S    LegalIndex            ; loop while index positive
  277.             MOVEQ    #0,D1                ; OK, use the first one
  278. FoundIt        
  279.             LEA        CTTable+rgb(A0,D1),A0 ; get the address of the color to use
  280.             MOVE.L    A0,D0                ; we'll need A0 in a second
  281.             MOVE.L    (SP)+,D1            ; restore the register
  282.             MOVE.L    (SP)+,A0            ; get the return address
  283.             MOVE.L    D0,-(SP)            ; push the rgb addr on the stack
  284.             JMP        (A0)                ; return to caller
  285.             
  286.             
  287. ;
  288. ;  DrawPBut draws the pushButton
  289. ;
  290. DrawPBut
  291.             TST.B    ContrlVis(A0)        ; is it visible?
  292.             BEQ.S    ButStub             ; if not, we're done
  293. ;
  294. ; calculate roundness as function of rectangle size
  295. ;
  296.             BSR     RoundCalc            ; compute roundNess factor in D4
  297.             
  298.             TST.B    IsColor(A6)            ; are we on a color system?
  299.             BEQ.S    @NoColor2            ; if on B&W, then skip
  300.         
  301. ;
  302. ; if pushbutton, paint bk to body color; if checkmark then erase to window content <C59/30Jun86> DAF
  303. ;
  304. @9            TST.B    D6                    ; is it a pushButton?
  305.             BEQ.S    @4                     ; 
  306.  
  307. ; set the window content color to the back for the eraseRRect        <C59/30Jun86> DAF
  308.             
  309.             PEA        ContentRGB(A6)        ; push the pointer to content color
  310.             BRA.S    @5
  311.             
  312. ; set the body color for button                                         <C59/30Jun86> DAF
  313. @4            
  314.             MOVE.L    (A3),A0                ; get control rec pointer
  315.             MOVE.B    contrlHilite(A0),D0    ; get the hilite byte
  316.             SUBQ.B    #1,D0                ; make 0->$FF
  317.             CMP.B    #$FD,D0                 ; is the control hilited?
  318.             BHS.S    @8                    ; no, so continue
  319.             MOVEQ    #cTextColor,D0        ; if it is, paint the button in text color
  320.             BRA.S    @0
  321. @8            MOVEQ    #cBodyColor,D0        ; if its not, then paint body color
  322. @0            BSR.S    SetUpColor            ; get info on the stack
  323. ;
  324. ; erase the bounding rectangle (if necessary)
  325. ;
  326. @5
  327.             _RGBBackColor                ; set it
  328.             MOVE.L    (A3),A0                ; get controlHandle again
  329.  
  330. @NoColor2                                ; END OF A COLOR-ONLY SECTION
  331.  
  332.             LEA     ContrlRect(A0),A4    ; get pointer to bounding rect
  333.             TST.B    D6                    ; is it a pushButton?
  334.             BEQ.S    EraseCBound         ; push buttons are always erased
  335.             TST.B    D3                    ; draw all?
  336.             BNE.S    SkipCErase            ; if not, don't bother to erase
  337. ;
  338. EraseCBound
  339.             MOVE.L    A4,-(SP)            ; push rect
  340.             MOVE.L    D4,-(SP)            ; push rounding factor
  341.             
  342.             _EraseRoundRect             ; paint it the background color
  343.             
  344. ;
  345. ;  save the current font and force the system font
  346. ;
  347. SkipCErase    MOVE.L    GrafGlobals(A5),A0    ; get GrafGlobals base
  348.             MOVE.L    ThePort(A0),A0        ; get current port
  349.             MOVE.L    txFont(A0),-(SP)    ; remember the font,face
  350.             MOVE.W    txSize(A0),-(SP)    ; remember the size
  351.  
  352.             SUBQ    #8,D7                ; was code 8 or greater?
  353.             BGE.S    @1                    ; if so, use window's font
  354.  
  355.             CLR.L    txFont(A0)            ; force system font, normal face
  356.             MOVE    #12,D0                ; assume size = 12
  357.  
  358.             TST.W    ROM85                ; new roms?                         <EHB 26Aug85>
  359.             BMI.S    @0                    ; => yes, use size = 12             <EHB 26Aug85>
  360.             MOVE.W    SysFontSize,D0        ; get default size                    <EHB 26Aug85>
  361.             BNE.S    @0                    ; => it's 0!                        <EHB 26Aug85>
  362.             MOVE.B    FMDefaultSize,D0    ; get default size                    <EHB 26Aug85>
  363. @0            MOVE.W    D0,txSize(A0)        ; set size of font                    <EHB 26Aug85>
  364.  
  365. @1            MOVE.L    ClipRgn(A0),-(SP)    ; push the current clipRgn handle
  366.  
  367. ; save old clip region and clip to the bounding rectangle sected with oldClip
  368.  
  369.             CLR.L    -(SP)                ; make space for region handle
  370.             _NewRgn                     ; allocate a region
  371.             MOVE.L    (SP),A2             ; remember region but leave on stack
  372.             _GetClip                    ; remember the current clipRgn
  373.             MOVE.L    (A3),A0             ; get control pointer
  374.             PEA     ContrlRect(A0)        ; push pointer to its bounding rect
  375.             _ClipRect                    ; make that the clipping region
  376.  
  377.             MOVE.L    A2,-(SP)            ; push the old ClipRgn
  378.             MOVE.L    4(SP),-(SP)         ; the answer goes into current clip
  379.             _SectRgn                    ; intersect new and old
  380.  
  381. ; Save off some registers for mondo button title calculations, then
  382. ; set them up for our use
  383.  
  384.             MOVEM.L D4/A2-A3,-(SP)        ; save registers                        <EHB 20-May-85>
  385.             MOVE.L    (A3),A0             ; get pointer to control
  386.             LEA     contrlTitle(A0),A2    ; get title into A2
  387.             LEA     contrlRect(A0),A4    ; get rect into A4                        <EHB 20-May-85>
  388.  
  389.             MOVEQ    #0,D7                ;                                        <EHB 20-May-85>
  390.             MOVE.B    (A2),D7             ; get string length into D7             <EHB 20-May-85>
  391.             BEQ     NoTitle             ; quick check for nothing                <EHB 20-May-85>
  392.  
  393. ; now count the number of lines in the title.  Lines are separated by CR's
  394.  
  395.             MOVEQ    #0,D4                ; save number of lines in D4            <EHB 20-May-85>
  396. @2
  397.             ADDQ    #1,D4                ; count next line                        <EHB 20-May-85>
  398.             BSR     Pt2Next             ; point to next line (index in D7)        <EHB 20-May-85>
  399.             TST.B    D7                    ; D7 < 0 if done                        <EHB 20-May-85>
  400.             BPL.S    @2                    ; => get next line                        <EHB 20-May-85>
  401.  
  402.             MOVE.B    (A2),D7             ; get string length back                <EHB 20-May-85>
  403.  
  404. ; now get a font info record on stack, pointer to it in A3
  405.  
  406.             SUBQ    #8,SP                ; make room for 4 INTEGERS                <EHB 20-May-85>
  407.             MOVE.L    SP,A3                ; save pointer in A3                    <EHB 20-May-85>
  408.             MOVE.L    A3,-(SP)            ; push pointer to record                <EHB 20-May-85>
  409.             _GetFontInfo                ; and fill the record                    <EHB 20-May-85>
  410.  
  411. ; Set up D5 to point to the baseline of the last line
  412.  
  413.             BSR     GetHeight            ; get height of line into D0            <EHB 20-May-85>
  414.             MULU    D4,D0                ; #lines times height                    <EHB 20-May-85>
  415.             MOVE.W    bottom(A4),D1        ; get bottom of rect                    <EHB 20-May-85>
  416.             MOVE.W    D1,D5                ; D5 will be baseline                    <EHB 20-May-85>
  417.             SUB.W    top(A4),D1            ; get height of rect                    <EHB 20-May-85>
  418.             SUB.W    D0,D1                ; get unused space                        <EHB 20-May-85>
  419.             ASR.W    #1,D1                ; and DIV by 2                            <EHB 20-May-85>
  420.             SUB.W    D1,D5                ; move up from bottom                    <EHB 20-May-85>
  421.             SUB.W    leading(A3),D5        ; to bottom of descender                <EHB 20-May-85>
  422.             SUB.W    descent(A3),D5        ; to first baseline                     <EHB 20-May-85>
  423. DoNextLine
  424.  
  425. ; get the width of the current line into D0
  426.  
  427.             BSR     Pt2Next             ; next line in D7, len in D3            <EHB 20-May-85>
  428.             CLR.W    -(SP)                ; make room for result                    <EHB 20-May-85>
  429.             MOVE.L    A2,-(SP)            ; push title pointer                    <EHB 20-May-85>
  430.             MOVE.W    D7,D0                ; get our offset into string            <EHB 20-May-85>
  431.             ADDQ.B    #2,D0                ; bump past length (or CR)                <EHB 20-May-85>
  432.             MOVE.W    D0,-(SP)            ; push true offset into string            <EHB 20-May-85>
  433.             MOVE.W    D3,-(SP)            ; push number of bytes                    <EHB 20-May-85>
  434.             _TextWidth                    ; get the string's width                <EHB 20-May-85>
  435.             MOVE.W    (SP)+,D0            ; and save result in D0             <EHB 20-May-85>
  436.  
  437. ; if it's a checkbox, don't center it, just move to right a little
  438.  
  439.             TST.B    D6                    ; is it a check box?
  440.             BEQ.S    ElCentro            ; => no, go center the string            <EHB 20-May-85>
  441.  
  442. ; adjust positioning for push button
  443.             
  444.             TST.W    ROM85                ; are we on an old mac                    <DAF 30-Mar-87> 
  445.             BMI.S    LeftBox                ; old mac, so always do left side        <DAF 30-Mar-87>
  446.             tst.w   teSysJust               ; right to left?                        <MED 27-Aug-86>
  447.             beq.s   LeftBox                 ; no, normal case                       <MED 27-Aug-86>
  448.             MOVE.W  right(A4),D1            ; get the right edge                    <MED 27-Aug-86>
  449.             SUB.W   left(A4),D1             ; get the width                         <MED 27-Aug-86>
  450.             SUB.W   D0,D1                   ; subtract string's width               <MED 27-Aug-86>
  451.             sub.w   #18,d1                  ; subtract room for box                 <MED 27-Aug-86>
  452.             ADD.W   left(A4),D1             ; and add into left                     <MED 27-Aug-86>
  453.             BRA.S   DrawBTitle              ; back to common code                   <MED 27-Aug-86>
  454.  
  455. LeftBox    
  456.             MOVE.W    Left(A4),D1         ; get the left edge
  457.             ADD.W    #18,D1                ; leave room for check box
  458.             BRA.S    DrawBTitle            ; back to common code
  459.  
  460. ElCentro            
  461. ; center the line in the rect
  462.  
  463.             MOVE.W    right(A4),D1        ; get the right edge
  464.             SUB.W    left(A4),D1         ; get the width
  465.             SUB.W    D0,D1                ; subtract string's width
  466.             ASR.W    #1,D1                ; get centering offset
  467.             ADD.W    left(A4),D1         ; and add into left
  468.  
  469. DrawBTitle
  470.             MOVE.W    D1,-(SP)            ; push horizontal position
  471.             MOVE.W    D5,-(SP)            ; and vertical position                 <EHB 20-May-85>
  472.             _MoveTo                     ; move the pen there
  473.  
  474. ; now that registers are free, push colors on stack     <C59/30Jun86> DAF
  475.  
  476.             TST.B    IsColor(A6)            ; are we on a color system?
  477.             BEQ.S    @NoColor4            ; if on B&W, then skip
  478.             
  479.             TST.B    D6                    ; is it a check box?
  480.             BNE.S    @1                    ; 
  481.  
  482.             MOVE.L    CtlHndl(A6),A0        ; get the control handle (not A3 in this section)    <DAF 29Apr86>
  483.             MOVE.L    (A0),A0             ; get control pointer
  484.             MOVE.B    ContrlHilite(A0),D0    ; need to handle the case of 254/5 hiliting
  485.             SUBQ    #1,D0                ; make 0 into 255
  486.             CMP.B    #$FD,D0                ; is it hilited?                        <DAF 29Apr86>
  487.             BHS.S    @1                    ; if not, go on                            <DAF 29Apr86>
  488.  
  489.             MOVE.W    #cBodyColor,D0        ; a button, so set body color
  490.             BRA.S    @4                    ; go on
  491. @1            
  492.             MOVE.W    #cTextColor,D0        ; set the text color
  493.             
  494. @4
  495.             BSR     SetUpColor            ; deposit appropriate values on stack
  496.             _RGBForeColor
  497. @NoColor4
  498.  
  499.             MOVE.L    A2,-(SP)            ; point to string                        <EHB 20-May-85>
  500.             MOVE.W    D7,D0                ; get our offset into string            <EHB 20-May-85>
  501.             ADDQ.B    #2,D0                ; bump past length (or CR)                <EHB 20-May-85>
  502.             MOVE.W    D0,-(SP)            ; push true offset into string            <EHB 20-May-85>
  503.             MOVE.W    D3,-(SP)            ; push length in bytes                    <EHB 20-May-85>
  504.             _DrawText                    ; this is where we draw the line
  505.  
  506. ; bump baseline point up to next line, test for end
  507.  
  508.             BSR      GetHeight            ; get line height into D0                <EHB 20-May-85>
  509.             SUB.W    D0,D5                ; go up to next base line                <EHB 20-May-85>
  510.             TST.B    D7                    ; done yet?                             <EHB 20-May-85>
  511.             BPL        DoNextLine            ; => nope                                <EHB 20-May-85>
  512.  
  513.             ADDQ    #8,SP                ; strip font record                     <EHB 20-May-85>
  514. NoTitle
  515.             MOVEM.L (SP)+,D4/A2-A3        ; and all those registers                <EHB 20-May-85>
  516.  
  517. ; restore original font, face and size
  518.  
  519.             MOVE.L    GrafGlobals(A5),A0    ; get GrafGlobals base
  520.             MOVE.L    ThePort(A0),A0        ; get current port
  521.             MOVE.W    (SP)+,txSize(A0)    ; restore the size
  522.             MOVE.L    (SP)+,txFont(A0)    ; restore the font,face
  523.  
  524. ;
  525. ; set the pen color to FrameColor            <C59/30Jun86> DAF
  526. ;
  527.  
  528.             TST.B    IsColor(A6)            ; are we on a color system?
  529.             BEQ.S    @NoColor5            ; if on B&W, then skip
  530.             
  531.             MOVEQ    #cFrameColor,D0        ;
  532.             BSR        SetUpColor            ;
  533.             _RGBForeColor                ;
  534.  
  535. @NoColor5                                ; END OF A COLOR-ONLY SECTION
  536.  
  537.             TST.B     D6                    ; is it a checkBox?
  538.             BNE     PlotCheck            ; if so, go draw it
  539.             
  540.             MOVE.L    A4,-(SP)            ; push the rectangle pointer
  541.             MOVE.L    D4,-(SP)            ; push rounding factor
  542.             _FrameRoundRect             ; frame the button
  543.  
  544. ;
  545. ; perform SpecialHilite if necessary
  546. ;
  547.             TST.B    IsColor(A6)            ; are we on a color system?
  548.             BEQ.S    @NoColor6            ; if on B&W, then skip
  549.             
  550.             MOVE.L    (A3),A0             ; get control pointer
  551.             CMP.B    #$FE,ContrlHilite(A0) ; is it the special hilite state?
  552.             BHS.S    SpecialHilite        ; if so, go do it
  553.             
  554.             BRA.S    @Common6            ; and continue...
  555.  
  556. @NoColor6            
  557. ;
  558. ; hilite the button if necessary
  559. ;
  560.             MOVE.L    (A3),A0             ; get control pointer
  561.             MOVE.B    ContrlHilite(A0),D0 ; is it hilited?
  562.             BEQ.S    DoneDrwBut            ; if not, we're done
  563. ;
  564.             CMP.B    #$FE,D0             ; is it the special hilite state?
  565.             BHS.S    SpecialHilite        ; if so, go do it
  566. ;
  567.             MOVE.L    A4,-(SP)            ; push rectangle
  568.             MOVE.L    D4,-(SP)            ; push rounding factor
  569.             _InverRoundRect             ; hilite by inverting
  570.  
  571. @Common6
  572.  
  573. ;
  574. ; restore original clipping region and we're done
  575. ;
  576. DoneDrwBut
  577.             _PenNormal                    ; set the pen back to normal
  578.             MOVE.L    A2,-(SP)            ; push old clip region
  579.             _SetClip                    ; restore it
  580.             MOVE.L    A2,-(SP)            ; dispose of temporary region
  581.             _DisposRgn                    ; de-allocate it
  582.             RTS                         ; all done!
  583.  
  584. ;------------
  585. ; Utility Pt2Next -- Point to next line within the title
  586. ;        On Entry:    A2        Title pointer
  587. ;                    D7        offset to end of next line to do
  588. ;        On Exit:    D7        offset to next line-2 (D7<0 if last line)
  589. ;                    D3        length of next line
  590.  
  591. CR            EQU      $0D                 ; CR = carriage return
  592.  
  593. Pt2Next
  594.             MOVEQ    #0,D3                ; clear out count                <EHB 20-May-85>
  595.             TST.B    D7                    ; pointing at count?            <EHB 20-May-85>
  596.             BEQ.S    @2                    ; => yes, a leading CR            <EHB 20-May-85>
  597. @1
  598.             CMP.B    #CR,0(A2,D7)        ; is char a CR?                 <EHB 20-May-85>
  599.             BEQ.S    @2                    ; => yes, all done                <EHB 20-May-85>
  600.             ADDQ    #1,D3                ; else bump count by one        <EHB 20-May-85>
  601.             SUBQ.B    #1,D7                ; and move back in string        <EHB 20-May-85>
  602.             BNE.S    @1                    ; => not end of string            <EHB 20-May-85>
  603. @2
  604.             SUBQ.B    #1,D7                ; prepare for next string        <EHB 20-May-85>
  605.             RTS                         ; D7 < 0 if last line            <EHB 20-May-85>
  606.  
  607. ;------------
  608. ; Utility GetHeight -- return in D0 the height of on line
  609. ;        On Entry:    A3        Font Record
  610. ;        On Exit:    D0        Line height
  611.  
  612. GetHeight
  613.             MOVEQ    #0,D0                ; clear out height                        <EHB 20-May-85>
  614.             ADD.W    ascent(A3),D0        ; height = ascent + descent + leading    <EHB 20-May-85>
  615.             ADD.W    descent(A3),D0        ;                                        <EHB 20-May-85>
  616.             ADD.W    leading(A3),D0        ;                                        <EHB 20-May-85>
  617.             RTS
  618.  
  619. ; SpecialHilite handles drawing the disabled button
  620.  
  621. SpecialHilite
  622.             BSR.S    DisableText
  623.             BRA.S    DoneDrwBut
  624. DisableText
  625.             TST.B    IsColor(A6)            ; are we on a color system?
  626.             BEQ.S    @NoColor7            ; if on B&W, then skip
  627.             
  628.             TST.B    D6                    ; is it a pushbutton?    
  629.             BNE.S    @NoColor7            ; a checkbox, so go
  630.             MOVEQ    #cTextColor,D0        ; set the colors apropos
  631.             BSR        SetUpColor            ;
  632.             _RGBForeColor                ;
  633.             MOVEQ    #cBodyColor,D0        ;
  634.             BSR        SetUpColor            ;
  635.             _RGBBackColor                ;
  636.             
  637. @NoColor7                                ; END OF A COLOR-ONLY SECTION            
  638.  
  639.             MOVE.L    A4,-(SP)            ; push    rectangle
  640.             MOVE.L    #$00010003,-(SP)
  641.             _InsetRect
  642.  
  643.             MOVE.L    A4,-(SP)
  644.  
  645.             MOVE.L    (A5),A0
  646.             PEA     Gray(A0)
  647.             _PenPat
  648.             MOVE    #patBIC,-(SP)
  649.             _PenMode
  650.  
  651.             _PaintRect                    ; gray it out
  652.             _PenNormal
  653.  
  654.             MOVE.L    A4,-(SP)
  655.             MOVE.L    #$FFFFFFFD,-(SP)
  656.             _InsetRect
  657.  
  658.             RTS
  659.  
  660. ; RoundCalc calculates the rounding factor in D4 based on the control's rect
  661.  
  662. RoundCalc
  663.             TST.B     D6                    ; is it a checkBox?
  664.             BNE.S    CheckRound            ; if so,    special case it
  665. ;
  666.             MOVE.W    ContrlRect+Bottom(A0),D4    ; get bottom coordinate
  667.             SUB.W    ContrlRect+Top(A0),D4    ; figure    out vertical height
  668.             LSR     #1,D4                ; scale it down by a factor of 2
  669.             MOVE    D4,D0                ; fill both halves with it
  670.             SWAP    D4                    ; get in    high part
  671.             MOVE    D0,D4                ; and in    low part
  672.             RTS
  673. ;
  674. CheckRound    MOVEQ    #0,D4                ; checkBoxes are    square!
  675.             RTS
  676. ;
  677. ; HitPBut handles the button hit-test
  678. ;
  679. HitPBut
  680.             MOVE.B    ContrlHilite(A0),D4 ; get hiliteState    <EHB 16-May-85>
  681.             ADDQ.B    #1,D4                ; is it 255?        <EHB 16-May-85>
  682.             BEQ.S    @1                    ; if so, skip
  683.  
  684.             CLR.W    -(SP)                ; make room for function result
  685.             MOVE.L    D3,-(SP)            ; push the point
  686.             PEA     ContrlRect(A0)        ; push address of rect
  687.             _PtInRect                    ; in the rectangle?
  688.             TST.B    (SP)+                ; examine result
  689.             BEQ.S    @1                    ; if not, we're done
  690.  
  691.             ADDQ.B    #1,D4                ; 254 hiliting?     <EHB 16-May-85>
  692.             BEQ.S    Return254            ; => say it is so    <EHB 16-May-85>
  693.  
  694.             MOVE    #inButton,22(A6)    ; return that it was
  695.             TST.B     D6                    ; a checkBox?
  696.             BEQ.S    @1                    ; if not, we're done
  697.             ADDQ    #1,22(A6)            ; if so, flag it
  698. @1            RTS
  699.  
  700. Return254
  701.             MOVE    #254,22(A6)         ; indicate its 254-disabled
  702.             RTS
  703. ;
  704. ; CalcPBut returns the bounding region of the button
  705. ;
  706. CalcPBut
  707.             TST.B     D6                    ; is it a checkBox?
  708.             BNE.S    CalcSquare            ; check box bounds are just rects
  709. ;
  710.             BSR.S    RoundCalc            ; calculate rounding factor
  711.             _HidePen                    ; dont draw anything
  712.             _OpenRgn
  713.  
  714.             MOVE.L    A3,A0                ; copy to A0 for HLock            <C424/18Nov86> DAF
  715.             _HLock                        ; lock it down                    <C424/18Nov86> DAF
  716.  
  717.             MOVE.L    (A3),A0             ; get pointer to control
  718.             PEA     ContrlRect(A0)        ; push rectangle pointer
  719.             MOVE.L    D4,-(SP)            ; push rounding factor
  720.             _FrameRoundRect             ; frame the button
  721.  
  722.             MOVE.L    D3,-(SP)            ; push the region
  723.             _CloseRgn                    ; make the rounded rectangular region
  724.             _ShowPen
  725.  
  726.             MOVE.L    A3,A0                ; copy to A0 for HLock            <C424/18Nov86> DAF
  727.             _HUnlock                    ; unlock the control            <C424/18Nov86> DAF
  728.  
  729. ;
  730. ; set the pattern for indicator dragging
  731. ;
  732. DragGray
  733.             MOVE.L    (A5),A0             ; get qDraw globals
  734.             LEA     Gray(A0),A0         ; point to gray pattern
  735.             MOVE.L    (A0)+,DragPattern    ; move in the 1st half
  736.             MOVE.L    (A0),DragPattern+4    ; move in the 2nd half
  737.             RTS                         ; all done!
  738. ;
  739. CalcSquare
  740.             MOVE.L    D3,-(SP)            ; push the region
  741.             PEA     ContrlRect(A0)        ; push the rectangle pointer
  742.             _RectRgn                    ; make a rectangular region
  743.             BRA.S    DragGray            ; all done -- go    set drag pattern
  744. ;
  745. ; PlotCheck takes care of drawing the actual check box of the check box button.  It
  746. ; figures out where to draw the box, draws it, and then checks it or not based on
  747. ; the current value and hilite state of the button
  748. ;
  749. PlotCheck
  750.  
  751. ; first set the window content color      <C59/30Jun86> DAF
  752.             TST.B    IsColor(A6)            ; are we on a color system?
  753.             BEQ.S    @NoColor8            ; if on B&W, then skip
  754.             
  755.             PEA        ContentRGB(A6)
  756.             _RGBBackColor                ;
  757. @NoColor8                                ; END OF A COLOR-ONLY SECTION
  758.  
  759.             SUBQ    #8,SP                ; allocate a rectangle on the stack
  760.             MOVE.W    bottom(A4),D0        ; get rect height                        <EHB 20-May-85>
  761.             MOVE.W    D0,D1                ; save a copy                            <EHB 20-May-85>
  762.             SUB.W    top(A4),D0            ; get height                            <EHB 20-May-85>
  763.             SUB.W    #12,D0                ; sub box height                        <EHB 20-May-85>
  764.             ASR.W    #1,D0                ; div by 2                                <EHB 20-May-85>
  765.             SUB.W    D0,D1                ; get offset from bottom                <EHB 20-May-85>
  766.             MOVE    D1,Bottom(SP)        ; set up the bottom                     <EHB 20-May-85>
  767.             SUB     #12,D1                ; compute the top                        <EHB 20-May-85>
  768.             MOVE    D1,Top(SP)            ; set up the top                        <EHB 20-May-85>
  769.  
  770.              TST.W    ROM85                ; are we on a 64K ROM Mac?                <DAF 30-Mar-87>
  771.             BMI.S    LeftBoxTitle        ; old mac, do it left to right            <DAF 30-Mar-87>
  772.             tst.w   teSysJust               ; right to left?                        <MED 27-Aug-86>
  773.              beq.s   LeftBoxTitle            ; no, normal case                       <MED 27-Aug-86>
  774.             MOVE    Right(A4),D1            ; get left edge of boundsRect           <MED 27-Aug-86>
  775.             subq    #2,D1                   ; indent 2 pixels                       <MED 27-Aug-86>
  776.             MOVE    D1,Right(SP)            ; that's the left of the checkRect      <MED 27-Aug-86>
  777.             sub     #12,D1                  ; compute right edge                    <MED 27-Aug-86>
  778.             MOVE    D1,Left(SP)             ; update the right edge                 <MED 27-Aug-86>
  779.             bra.s   EraseCheck              ; continue                              <MED 27-Aug-86>
  780.             
  781. LeftBoxTitle
  782.             MOVE    Left(A4),D1         ; get left edge of boundsRect            <EHB 20-May-85>
  783.             ADDQ    #2,D1                ; indent 2 pixels                        <EHB 20-May-85>
  784.             MOVE    D1,Left(SP)         ; that's the left of the checkRect      <EHB 20-May-85>
  785.             ADD     #12,D1                ; compute right edge                    <EHB 20-May-85>
  786.             MOVE    D1,Right(SP)        ; update the right edge                 <EHB 20-May-85>
  787.  
  788. EraseCheck
  789. ;
  790. ; erase the check box
  791. ;
  792.             MOVE.L    SP,-(SP)            ; push rectangle pointer
  793.             _EraseRect                    ; erase it
  794. ;
  795. ; OK, now we must fill in the checkBox rectangle based on the value and hilite state
  796. ; of the control
  797. ;
  798.             MOVE.L    (A3),A0             ; get control handle
  799.             MOVE.W    ContrlValue(A0),D5    ; get the value
  800.             MOVE.B    ContrlHilite(A0),D0 ; is it hilited?
  801.             BEQ.S    FrameCheck            ; if not, skip
  802. ;
  803. ; its hilited so up the penSize to indicate its hilited
  804. ;
  805.             CMP.B    #$FE,D0             ; disabled?
  806.             BLO.S    SkipDis             ; if so,    skip doubling
  807. ;
  808.             BSR     DisableText
  809.  
  810.             BRA.S    FrameCheck
  811.  
  812. SkipDis
  813.             MOVE.L    #$00020002,-(SP)
  814.             _PenSize                    ; up the penSize
  815. FrameCheck
  816.             MOVE.L    SP,-(SP)            ; push the rectangle
  817.  
  818.             CMP.B    #2,D6                ; test for radio button
  819.             BEQ.S    @1                    ; if its a radio button, go do it
  820.             _FrameRect                    ; frame it
  821.             BRA.S    @2
  822. @1
  823.             _FrameOval
  824. @2
  825.             _PenNormal
  826. ;
  827. ; now we can draw the check if we're supposed to
  828. ;
  829.             LSR     #1,D5                ; check out the low bit of D5
  830.             BCC.S    DonePCheck            ; if its off, we're done
  831. ;
  832.             CMP.W    #2,D6                ; test for radio button
  833.             BEQ.S    DrawRButton         ; if its a radio button, go do it
  834. ;
  835.             MOVE.L    SP,-(SP)            ; push the rectangle pointer
  836.             MOVE.L    OneOne,-(SP)        ; push the inset factor
  837.             _InsetRect                    ; inset the rectangle
  838.  
  839.             MOVE.L    TopLeft(SP),-(SP)    ; push top left
  840.             _MoveTo                     ; move to it
  841.             MOVE.L    BotRight(SP),-(SP)    ; push bottom right
  842.             _LineTo                     ; draw one line of the cross
  843. ;
  844.             MOVE    Right(SP),-(SP)     ; push right
  845.             MOVE    Top+2(SP),-(SP)     ; push top
  846.             SUBQ    #1,(SP)             ; bias the top
  847.             _MoveTo                     ; move to it
  848.             MOVE    Left(SP),-(SP)        ; push left
  849.             SUBQ    #1,(SP)             ; bias the left
  850.             MOVE    Bottom+2(SP),-(SP)    ; push bottom
  851.             _LineTo                     ; draw the line
  852.             BRA.S    DonePCheck
  853. ;
  854. ;  draw the radio button check mark -- a little circle
  855. ;
  856. DrawRButton
  857.             MOVE.L    SP,-(SP)            ; push pointer to rect
  858.             MOVE.L    #$00030003,-(SP)    ; push inset factor
  859.             _InsetRect                    ; inset it
  860.             MOVE.L    SP,-(SP)            ; push rect again
  861.             _PaintOval                    ; draw the circle?
  862. ;
  863. DonePCheck
  864.             ADDQ    #8,SP                ; pop off the rectangle
  865.             BRA     DoneDrwBut            ; all done!
  866.  
  867.             END